/************************************************************************/
/* Âß¼­¹ÜÀí·þÎñÆ÷£º×´Ì¬»ú                                                                     */
/************************************************************************/

#pragma once
#include <queue>
#include "basetype.h"
#include "basethread.h"

enum STATEPHASE
{
    ENTER,
    LEAVE,
    MOVENEXT,
};

class CHasUnit;
class CUnit
{
    friend    class StateTimeComp;
    friend    class StateMgr;
    friend    class CHasUnit;
    friend    class State;

private:
    CHasUnit*    m_data;
    int        m_id;
    int        m_time;
    bool    m_valid;
};

class StateMgr;

class CHasUnit
{
    friend class StateMgr;
public:
    CHasUnit();
    int            getStateID();

    void        installState(int pID, int pTime);
    void        moveNext();
    void        setCurrentValied(bool pValied);
    void        setStateID(int pID);
private:
    void        setCurrentUnit(CUnit* pUnit);
private:

    CUnit*        m_currentUnit;
    int            m_currentStateID;

protected:
    void        setStateMgr(StateMgr*);
private:
    StateMgr*        m_stateMgr;
};

class StateTimeComp : public std::binary_function<CUnit*, CUnit*, bool>
{
public:
    bool operator()( const first_argument_type& left,
                     const second_argument_type& right )
    {
        return left->m_time > right->m_time;
    }
};

class State
{
    friend    class StateMgr;
protected:
    State(void);
    ~State(void);
    int                getID();
    void            setID(int);

    void            execute(CHasUnit*, STATEPHASE);
protected:
    virtual    void    onEnter(CHasUnit*)    {};
    virtual void    onLeave(CHasUnit*)    {};
    virtual    void    moveNext(CHasUnit*)    {};
    int                m_overTime;
private:
    int                m_id;
};

using namespace ThreadLib;

class    StateMgr : public AbstractThread
{
public:
    StateMgr();
    void    addState(State*);
    void    installState(int id,CHasUnit*,int time);
    void    executeState(int,CHasUnit*,STATEPHASE);
    void    schedule();
private:
    State*    m_states[0xFFFF];

    void    Run();

    TypePoll<true, CUnit, 1000>                                    m_unitPoll;
    priority_queue< CUnit, std::vector<CUnit*>, StateTimeComp >    m_stateQueue;
};

